﻿using System.ComponentModel;
using Newtonsoft.Json.Linq;

namespace Acme.MeiTuan.SDK.Tools;

public static class ObjectToDictionaryHelper
{
    public static IDictionary<string, object> ToDictionary(this object source)
    {
        return source.ToDictionary<object>();
    }

    public static IDictionary<string, T> ToDictionary<T>(this object source)
    {
        if (source == null)
        {
            ThrowExceptionWhenSourceArgumentIsNull();
        }

        var dictionary = new Dictionary<string, T>();
        foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(source))
        {
            AddPropertyToDictionary(property, source, dictionary);
        }

        return dictionary;
    }

    public static IDictionary<string, string> BodyDic(this IDictionary<string, string> list, string json)
    {
        var jo = JObject.Parse(json);
        foreach (var item in jo)
        {
            //var jval = item.Value as JValue;
            //if (jval == null)
            //    continue;
            var hasValue = false;
            switch (item.Value.Type)
            {
                case JTokenType.Array:
                case JTokenType.Object:
                    if (item.Value.HasValues)
                    {
                        hasValue = true;
                    }

                    break;
                case JTokenType.String:
                case JTokenType.Bytes:
                case JTokenType.Integer:
                case JTokenType.Float:
                case JTokenType.Date:
                case JTokenType.Boolean:
                case JTokenType.Guid:
                    if (!string.IsNullOrWhiteSpace(item.Value.ToString()))
                    {
                        hasValue = true;
                    }

                    break;
            }

            if (hasValue)
            {
                list.Add(item.Key,
                    item.Value.ToString().Replace("\n", "").Replace("\t", "").Replace("\r", "").Replace(" ", ""));
            }
        }

        return list;
    }

    private static void AddPropertyToDictionary<T>(PropertyDescriptor property, object source,
        Dictionary<string, T> dictionary)
    {
        var value = property.GetValue(source);
        dictionary.Add(property.Name, (T)value);
    }

    private static void ThrowExceptionWhenSourceArgumentIsNull()
    {
        throw new ArgumentNullException("source",
            "Unable to convert object to a dictionary. The source object is null.");
    }
}